package com.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConstructorUtils;
import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.ComparatorUtils;
import org.apache.commons.collections.comparators.ComparableComparator;
import org.apache.commons.collections.comparators.ComparatorChain;

public class BeanUtilDemo {

	public static void main(String[] args) throws Exception {
		// BeanUtils可以直接get和set一个属性的值。它将property分成3种类型：
		// Simple——简单类型，如Stirng、Int……
		// Indexed——索引类型，如数组、arrayList……
		// Maped——这个不用说也该知道，就是指Map啦，比如HashMap……
		Person p = new Person("zsl", 19, new ArrayList<Address>(){{
			add(new Address("aa@173.com", "东直门"));
			add(new Address("daiu@123.com", "西直门"));
		}}, new School("二十七"));
		System.out.println(BeanUtils.getProperty(p, "name"));

		Map<String, String> am = new HashMap<>();
		am.put("1", "234-222-1222211");
		am.put("2", "021-086-1232323");
		System.out.println(BeanUtils.getProperty(am, "2"));
		BeanUtils.setProperty(am, "telephone", "123897661");
		System.out.println(BeanUtils.getProperty(am, "telephone"));

		BeanUtils.setProperty(p, "addressList[0]", new Address("aa22@173.com", "东直门"));
		System.out.println(p);
		System.out.println(BeanUtils.getProperty(p, "addressList[0]"));
		System.out.println(BeanUtils.getProperty(p, "school.name"));

		//动态设定Bean按照哪个属性来排序，而不再需要在bean的Compare接口进行复杂的条件判断。
		//其中ComparatorChain属于jakata commons-collections包。
		//如果age属性不是普通类型，构造函数需要再传入一个comparator对象为age变量排序。
		List<Person> peoples = new ArrayList<Person>(){{
			add(new Person("zsl", 12));
			add(new Person("zsl2", 100));
			add(new Person("zsl3", 21));
			add(new Person("zsl2", 21));
		}};
		Collections.sort(peoples, new BeanComparator("age"));
		System.out.println(peoples);
		List<BeanComparator<Person>> sortFields = new ArrayList<>();
		sortFields.add(new BeanComparator<Person>("name"));
		sortFields.add(new BeanComparator<Person>("age"));
		ComparatorChain multiSort = new ComparatorChain(sortFields);
		Collections.sort(peoples, multiSort);
		System.out.println(peoples);
		//另外, BeanCompartor本身的ComparebleComparator, 遇到属性为null就会抛出异常, 也不能设定升序还是降序。
		//这个时候又要借助commons-collections包的ComparatorUtils.
		Comparator mycmp = ComparableComparator.getInstance();
		mycmp = ComparatorUtils.nullLowComparator(mycmp);  //允许null
		mycmp = ComparatorUtils.reversedComparator(mycmp); //逆序
		Comparator<Person> cmp = new BeanComparator<>("age", mycmp);
		Collections.sort(peoples, cmp);
		System.out.println(peoples);

		//PropertyUtils，当属性为Collection,Map时的动态读取：
		//Collection: 提供index
		//BeanUtils.getIndexedProperty(orderBean,"items",1);
		//或者
		//BeanUtils.getIndexedProperty(orderBean,"items[1]");
		//Map: 提供Key Value
		//BeanUtils.getMappedProperty(orderBean, "items","111");//key-value goods_no=111
		//或者
		//BeanUtils.getMappedProperty(orderBean, "items(111)")

		//PropertyUtils，获取属性的Class类型
		System.out.println(PropertyUtils.getPropertyType(p, "addressList").getName());

		//ConstructorUtils，动态创建对象
		System.out.println(ConstructorUtils.invokeConstructor(Person.class, new Object[]{"zsl", 12}));

		//MethodUtils，动态调用方法
		System.out.println(MethodUtils.invokeMethod(p, "getAge", null));

		Map map = BeanUtils.describe(p);
		Set keySet = map.keySet();
		for (Iterator iter = keySet.iterator(); iter.hasNext();) {
			Object element = (Object) iter.next();
			System.out.println("KeyClass:" + element.getClass().getName());
			System.out.println("ValueClass:" + map.get(element).getClass().getName());
			System.out.print(element + "\t");
			System.out.print(map.get(element));
			System.out.println();
		}
	}

}
